/* animation Type
 * Gravity 
 */

function applyPhysics(anim, particle) {
    // physics globals
    var gravity = 1500; // pixels / second^2
    var collisionDamper = 0.8; // 80% velocity lost when
    var floorFriction = 100; // pixels / second^2
    var timeInterval = anim.getTimeInterval();
    var canvas = anim.getCanvas();
    // gravity
    particle.vy += gravity * timeInterval / 1000;
    // position
    particle.y += particle.vy * timeInterval / 1000;
    particle.x += particle.vx * timeInterval / 1000;
    // floor condition
    if (particle.y > (canvas.height - particle.radius)) {
        particle.y = canvas.height - particle.radius;
        particle.vy *= -1;
        particle.vy *= collisionDamper;
    }
    // floor friction
    if (particle.y === canvas.height - particle.radius) {
        if (particle.vx > 0.1) {
            particle.vx -= floorFriction * timeInterval /
                    1000;
        }
        else if (particle.vx < -0.1) {
            particle.vx += floorFriction * timeInterval /
                    1000;
        }
        else {
            particle.vx = 0;
        }
    }
    // ceiling condition
    if (particle.y < (particle.radius)) {
        particle.y = particle.radius;
        particle.vy *= -1;
        particle.vy *= collisionDamper;
    }
    // right wall condition
    if (particle.x > (canvas.width - particle.radius)) {
        particle.x = canvas.width - particle.radius;
        particle.vx *= -1;
        particle.vx *= collisionDamper;
    }
    // left wall condition
    if (particle.x < (particle.radius)) {
        particle.x = particle.radius;
        particle.vx *= -1;
        particle.vx *= collisionDamper;
    }
}


/* Animation type
 * moving in an area
 */
var HeartAnimation = function(canvasId) {
    var max_size = 25;
    var max_particles = 250;
    var min_vel = 100;
    var max_generation_per_frame = 10;
// #Variables
// sometimes i wrote code horrible enouhg to make eyes bleed 
    var canvas = document.getElementById(canvasId);
    var ctx = canvas.getContext('2d');
    var height = canvas.height;
    var center_y = height / 2;
    var width = canvas.width;
    var center_x = width / 2;
    var animate = true;
    var particles = [];
    var last = Date.now(), now = 0;
    var died = 0, len = 0, dt;
    function isInsideHeart(x, y) {
        x = ((x - center_x) / (center_x)) * 3;
        y = ((y - center_y) / (center_y)) * -2;
        // Simplest Equation of lurve
        var x2 = x * x;
        var y2 = y * y;
        // Simplest Equation of lurve

        return (Math.pow((x2 + y2 - 1), 3) - (x2 * (y2 * y)) < 0);
    }

    function random(size, freq) {
        var val = 0;
        var iter = freq;
        do {
            size /= iter;
            iter += freq;
            val += size * Math.random();
        } while (size >= 1);
        return val;
    }

    function Particle() {
        var x = center_x;
        var y = center_y;
        var size = ~~random(max_size, 2.4);
        var x_vel = ((max_size + min_vel) - size) / 2 - (Math.random() * ((max_size + min_vel) - size));
        var y_vel = ((max_size + min_vel) - size) / 2 - (Math.random() * ((max_size + min_vel) - size));
        var nx = x;
        var ny = y;
        var r, g, b, a = 0.05 * size;
        this.draw = function() {
            r = ~~(255 * (x / width));
            g = ~~(255 * (1 - (y / height)));
            b = ~~(255 - r);
            ctx.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
            ctx.beginPath();
            ctx.arc(x, y, size, 0, Math.PI * 2, true);
            ctx.closePath();
            ctx.fill();
        }

        this.move = function(dt) {

            nx += x_vel * dt;
            ny += y_vel * dt;
            if (!isInsideHeart(nx, ny)) {
                if (!isInsideHeart(nx, y)) {
                    x_vel *= -1;
                    return;
                }

                if (!isInsideHeart(x, ny)) {
                    y_vel *= -1;
                    return;
                }
                // Lets do the crazy furbidden
                x_vel = -1 * y_vel;
                y_vel = -1 * x_vel;
                return;
            }

            x = nx;
            y = ny;
        }

    }

    function movementTick() {
        var len = particles.length;
        var dead = max_particles - len;
        for (var i = 0; i < dead && i < max_generation_per_frame; i++) {
            particles.push(new Particle());
        }

        // Update the date
        now = Date.now();
        dt = last - now;
        dt /= 1000;
        last = now;
        particles.forEach(function(p) {
            p.move(dt);
        });
    }

    function tick() {
        height = canvas.height;
        center_y = height / 2;
        width = canvas.width;
        center_x = width / 2;
        ctx.clearRect(0, 0, document.body.clientWidth, document.body.clientHeight);
        particles.forEach(function(p) {
            p.draw();
        });
        requestAnimationFrame(tick);
    }

    this.start = function() {

    }

    this.done = function() {

    }

    setInterval(movementTick, 16);
    tick();
}

/**
 * 
 * @param Animation anim
 * @param Particle particle
 * @returns {undefined}
 */
var logdata = {};
var index = 0;
var tickCount = 0;
function bokehFloating(anim, particle) {
    // physics globals
    var timeInterval = anim.getTimeInterval();
    particle.y += particle.vy * timeInterval / 1000;
    particle.x += particle.vx * timeInterval / 1000;
    particle.tickTime++;
    if (Math.abs(particle.vx) <= particle.vmaxx) {
        particle.vx += particle.ax * timeInterval / 1000;
    } else {
        particle.vx = (particle.vx > 0 ? 1 : -1) * particle.vmaxx;
    }
    if (Math.abs(particle.vy) <= particle.vmaxy) {
        particle.vy += particle.ay * timeInterval / 1000;
    }
    else
        particle.vy = (particle.vy > 0 ? 1 : -1) * particle.vmaxy;
    if (particle.x > anim.canvas.width - particle.radius) {
        particle.ax = -parseInt(Math.random() * 25);
        index++;
    }
    if (particle.x < 0) {
        particle.ax = parseInt(Math.random() * 25);
        index++;
    }
    if (particle.y > anim.canvas.height - particle.radius) {
        particle.ay = -parseInt(Math.random() * 25);
        index++;
    }
    if (particle.y < 0) {
        particle.ay = parseInt(Math.random() * 25);
        index++;
    }
}

var BokehElement = function() {

}

var screenWidth = 1366;
var screenHeight = 768;

function count(object) {
    var key, count = 0;
    for (key in object) {
        if (object.hasOwnProperty(key)) {
            count++;
        }
    }
    return count;
}